package com.net

import com.netease.yunxin.kit.alog.ALog
import com.netease.yunxin.kit.common.ui.utils.ToastUtils
import com.netease.yunxin.kit.common.ui.utils.ToastUtils.showErrorToast
import com.netease.yunxin.kit.common.ui.utils.ToastUtils.toast
import io.reactivex.*
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.functions.Consumer
import io.reactivex.schedulers.Schedulers
import org.json.JSONObject

/**
 * User: wujinsheng1@yy.com
 * Date: 2020/11/8 14:02
 * ModifyTime: 14:02
 * Description:
 */
object RxCompat {
    const val TAG = "RxUtils"
    fun <T> runOnFlowable(callback: () -> T) {
        Flowable.create<T>({
            it.onNext(callback.invoke())
        }, BackpressureStrategy.MISSING).observeOn(Schedulers.io()).subscribeOn(Schedulers.io())
            .subscribe()
    }

    fun <T> runOnMainFlowable(callback: () -> T) {
        Flowable.create<T>({
            it.onNext(callback.invoke())
        }, BackpressureStrategy.MISSING).observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(AndroidSchedulers.mainThread()).subscribe()
    }

    /**
     * 统一线程处理
     *
     * @param <T>
     * @return
    </T> */
    fun <T> schedulersTransformer(): ObservableTransformer<T, T> {
        return ObservableTransformer { upstream ->
            upstream.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
        }
    }

    fun <T> schedulersTransformerForFlowable(): FlowableTransformer<T, T> {
        return FlowableTransformer { upstream ->
            upstream.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
        }
    }

    fun errorConsumer(target: Any): Consumer<in Throwable> {
        return Consumer { throwable ->
            ALog.e(TAG, "target:$target,throwable:$throwable")
            optMsg(target, throwable)
        }
    }

    fun optMsg(target: Any, throwable: Throwable) {
        try {
            val jsonObj = JSONObject(throwable.message ?: "")
            jsonObj?.optString("msg")?.let { msg ->
                ALog.e(TAG, "target:$target,throwable:$throwable")
            } ?: kotlin.run {
                ALog.e(TAG, "target:$target,throwable:$throwable")
            }
        } catch (ex: Exception) {
            ALog.e(TAG, "target:$target,throwable:$throwable")
        }
    }

    private fun printStackTrace(errorReason: Array<StackTraceElement>): String {
        val stringBuilder = StringBuilder()
        for (item in errorReason) {
            stringBuilder.append(item.toString() + "\n")
        }
        return stringBuilder.toString()
    }

    fun dispose(disposable: Disposable?) {
        if (disposable != null && !disposable.isDisposed) {
            disposable.dispose()
        }
    }

    fun <T> schedulersIO(): ObservableTransformer<T, T>? {
        return ObservableTransformer { upstream ->
            upstream.subscribeOn(Schedulers.io()).observeOn(Schedulers.io())
        }
    }

    fun <T> schedulersMybeIO(): MaybeTransformer<T, T>? {
        return MaybeTransformer { upstream ->
            upstream.subscribeOn(Schedulers.io()).observeOn(Schedulers.io())
        }
    }

    fun <T> schedulersMybe(): MaybeTransformer<T, T>? {
        return MaybeTransformer { upstream ->
            upstream.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
        }
    }
}